#!/usr/bin/env python3

import argparse, platform, os, shutil, pathlib, subprocess, urllib.request

brew_deps = [
    'bash-completion', 'cloc', 'doxygen', 'python3', 'ruby', 'cmake', 'htop', 'conan', 'lua', 'cppcheck',
    'flake8', 'vim', 'clang-format', 'gcc', 'lcov', 'rsync', 'bash', 'python', 'the_silver_searcher', 'tree',
    'wget', 'swig', 'doxygen', 'golangci-lint', 'gopls', 'go', 'gradle', 'graphviz', 'ninja', 'sphinx-doc',
]

brew_casks = [
    'iterm2', 'keepassx', 'karabiner-elements'
]

apts = [
    'sudo', 'htop', 'curl', 'wget', 'strace', 'ack', 'silversearcher-ag',
    'git', 'gcc', 'g++', 'clang', 'cmake', 'valgrind', 'gdb', 'lldb', 'vim',
    'clang-tidy', 'clang-format', 'doxygen', 'python3', 'python3-pip', 'python3-dev',
    'build-essential', 'golang', 'swig', 'gopls', 'gradle', 'ninja-build',
    'default-jdk', 'default-jre', 'lcov', 'python3-sphinx',
]

chocos = [
    'vim', 'git', 'mingw', 'golang', 'golangci-lint', 'ag', 'cmake',
]

os.system("") # Windows is cursed

RESET = '\033[0m'
RED = '\033[91m'
GREEN = '\033[92m'
YELLOW = '\033[93m'

home = pathlib.Path.home()

def run(cmd):
    print(f'{YELLOW}Running command:{RESET} {GREEN}{cmd}{RESET}')
    rc = os.system(cmd)
    if rc != 0:
        print(f'{RED}Failed while running command:{RESET} {cmd}')

def fetch(url):
    with urllib.request.urlopen(url) as response:
        return response.read().decode()

def write_file(file, content_fn):
    if not file.exists():
        print(f'{YELLOW}Write file:{RESET} {GREEN}{file}{RESET}')
        content = content_fn()
        file.parent.mkdir(parents=True, exist_ok=True)
        with open(file, 'w') as f:
            f.write(content)

def link_file(link, file):
    if not link.exists() or not link.samefile(file):
        print(f'{YELLOW}Install file:{RESET} {GREEN}{link}{RESET} -> {GREEN}{file}{RESET}')
        link.parent.mkdir(parents=True, exist_ok=True)
        link.unlink(missing_ok=True)
        if platform.system() == 'Windows':
            link.hardlink_to(file)
        else:
            link.symlink_to(file)

parser = argparse.ArgumentParser()
parser.add_argument('-i', '--interactive', action='store_true')
parser.add_argument('-l', '--local', action='store_true')
parser.add_argument('-f', '--files', action='store_true')
parser.add_argument('-d', '--deps', action='store_true')
args = parser.parse_args()

if args.interactive:
    parser.print_help()
    args = parser.parse_args(args=input('Enter options: ').split(' '))

if args.deps:
    match platform.system():
        case 'Windows':
            run(f'choco install -y {' '.join(chocos)}')
        case 'Linux':
            run(f'sudo apt-get -y update && sudo apt-get -y upgrade && sudo apt-get -y dist-upgrade && sudo apt-get -y install {' '.join(apts)}')
            run('curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.55.2')
        case 'Darwin':
            if shutil.which('brew') is None:
                run('/bin/bash -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"')
            run(f'brew install {' '.join(brew_deps)}')
            run(f'brew install --cask {' '.join(brew_casks)}')
    if platform.system() == 'Windows':
        write_file(home.joinpath('vimfiles/autoload/plug.vim'), lambda: fetch('https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim'))
    else:
        write_file(home.joinpath('.vim/autoload/plug.vim'), lambda: fetch('https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim'))
    run('vim +PlugInstall +qa')

if args.files:
    dotfiles = pathlib.Path('dotfiles')
    for file in dotfiles.rglob('*'):
        if file.is_file():
            link_file(home / file.relative_to(dotfiles), dotfiles.joinpath(file.relative_to(dotfiles)).absolute())
    if platform.system() == 'Windows':
        link_file(home.joinpath('_vimrc'), home.joinpath('.vimrc'))
    else:
        link_file(home.joinpath('.bash_profile'), dotfiles.joinpath('.bashrc').absolute())

if args.local:
    email = subprocess.check_output(['git', 'log', '-1', "--pretty=format:%ae"]).decode()
    name = subprocess.check_output(['git', 'log', '-1', "--pretty=format:%an"]).decode()
    write_file(home.joinpath('.gitconfig.local'), lambda: f'[user]\n    email = {email}\n    name = {name}')
